"""
战斗服务器监控和告警系统
"""
import logging
import smtplib
import requests
import threading
import time
from datetime import datetime, timedelta
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Any
from enum import Enum
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import json
import psutil
from django.conf import settings
from django.core.mail import send_mail
from django.utils import timezone

logger = logging.getLogger(__name__)


class AlertLevel(Enum):
    """告警级别"""
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"


class AlertType(Enum):
    """告警类型"""
    PORT_EXHAUSTION = "port_exhaustion"
    SERVER_UNHEALTHY = "server_unhealthy"
    HIGH_MEMORY_USAGE = "high_memory_usage"
    HIGH_CPU_USAGE = "high_cpu_usage"
    BATTLE_ID_MISMATCH = "battle_id_mismatch"
    SERVER_STARTUP_FAILURE = "server_startup_failure"
    CONNECTION_ERROR = "connection_error"
    PROCESS_CRASH = "process_crash"
    STATE_INCONSISTENCY = "state_inconsistency"
    STATE_RECOVERY = "state_recovery"
    SERVER_CRASH = "server_crash"
    RESOURCE_USAGE = "resource_usage"
    SERVER_STARTUP_SUCCESS = "server_startup_success"


@dataclass
class Alert:
    """告警信息"""
    alert_type: AlertType
    level: AlertLevel
    message: str
    battle_id: Optional[str] = None
    port: Optional[int] = None
    timestamp: datetime = field(default_factory=timezone.now)
    metadata: Dict = field(default_factory=dict)
    
    def to_dict(self) -> Dict:
        """转换为字典格式"""
        return {
            'alert_type': self.alert_type.value,
            'level': self.level.value,
            'message': self.message,
            'battle_id': self.battle_id,
            'port': self.port,
            'timestamp': self.timestamp.isoformat(),
            'metadata': self.metadata
        }


@dataclass
class MonitoringMetrics:
    """监控指标"""
    total_servers: int = 0
    running_servers: int = 0
    unhealthy_servers: int = 0
    used_ports: int = 0
    available_ports: int = 0
    cpu_usage: float = 0.0
    memory_usage: float = 0.0
    disk_usage: float = 0.0
    network_connections: int = 0
    timestamp: datetime = field(default_factory=timezone.now)
    
    # 新增详细系统资源字段
    cpu_count: int = 0
    cpu_freq_current: float = 0.0
    cpu_freq_max: float = 0.0
    memory_total: int = 0  # 总内存 (bytes)
    memory_available: int = 0  # 可用内存 (bytes)
    memory_used: int = 0  # 已用内存 (bytes)
    disk_total: int = 0  # 总磁盘空间 (bytes)
    disk_used: int = 0  # 已用磁盘空间 (bytes)
    disk_free: int = 0  # 可用磁盘空间 (bytes)
    disk_partitions: List[Dict] = field(default_factory=list)  # 磁盘分区信息
    network_io_sent: int = 0  # 网络发送字节数
    network_io_recv: int = 0  # 网络接收字节数
    load_average: List[float] = field(default_factory=list)  # 系统负载平均值
    boot_time: float = 0.0  # 系统启动时间
    
    # 新增进程和请求指标
    process_count: int = 0  # 系统进程总数
    python_process_count: int = 0  # Python进程数
    django_process_count: int = 0  # Django进程数
    request_count_total: int = 0  # 总请求数
    request_count_per_minute: float = 0.0  # 每分钟请求数
    
    def to_dict(self) -> Dict:
        """转换为字典格式"""
        return {
            'total_servers': self.total_servers,
            'running_servers': self.running_servers,
            'unhealthy_servers': self.unhealthy_servers,
            'used_ports': self.used_ports,
            'available_ports': self.available_ports,
            'cpu_usage': self.cpu_usage,
            'memory_usage': self.memory_usage,
            'disk_usage': self.disk_usage,
            'network_connections': self.network_connections,
            'timestamp': self.timestamp.isoformat(),
            # 新增字段
            'cpu_count': self.cpu_count,
            'cpu_freq_current': self.cpu_freq_current,
            'cpu_freq_max': self.cpu_freq_max,
            'memory_total': self.memory_total,
            'memory_available': self.memory_available,
            'memory_used': self.memory_used,
            'disk_total': self.disk_total,
            'disk_used': self.disk_used,
            'disk_free': self.disk_free,
            'disk_partitions': self.disk_partitions,
            'network_io_sent': self.network_io_sent,
            'network_io_recv': self.network_io_recv,
            'load_average': self.load_average,
            'boot_time': self.boot_time,
            'process_count': self.process_count,
            'python_process_count': self.python_process_count,
            'django_process_count': self.django_process_count,
            'request_count_total': self.request_count_total,
            'request_count_per_minute': self.request_count_per_minute
        }


class AlertHandler:
    """告警处理器基类"""
    
    def handle_alert(self, alert: Alert) -> bool:
        """处理告警，返回是否成功"""
        raise NotImplementedError


class LogAlertHandler(AlertHandler):
    """日志告警处理器"""
    
    def handle_alert(self, alert: Alert) -> bool:
        """记录告警到日志"""
        try:
            log_level = {
                AlertLevel.INFO: logging.INFO,
                AlertLevel.WARNING: logging.WARNING,
                AlertLevel.ERROR: logging.ERROR,
                AlertLevel.CRITICAL: logging.CRITICAL
            }.get(alert.level, logging.INFO)
            
            logger.log(log_level, f"[ALERT] {alert.alert_type.value}: {alert.message}")
            return True
        except Exception as e:
            logger.error(f"Failed to log alert: {e}")
            return False


class EmailAlertHandler(AlertHandler):
    """邮件告警处理器"""
    
    def __init__(self, recipients: List[str]):
        self.recipients = recipients
    
    def handle_alert(self, alert: Alert) -> bool:
        """发送邮件告警"""
        try:
            if alert.level in [AlertLevel.ERROR, AlertLevel.CRITICAL]:
                subject = f"[{alert.level.value.upper()}] 战斗服务器告警: {alert.alert_type.value}"
                message = f"""
告警类型: {alert.alert_type.value}
告警级别: {alert.level.value}
告警消息: {alert.message}
战斗ID: {alert.battle_id or 'N/A'}
端口: {alert.port or 'N/A'}
时间: {alert.timestamp}
元数据: {json.dumps(alert.metadata, indent=2)}
                """
                
                send_mail(
                    subject=subject,
                    message=message,
                    from_email=settings.DEFAULT_FROM_EMAIL,
                    recipient_list=self.recipients,
                    fail_silently=False
                )
                return True
        except Exception as e:
            logger.error(f"Failed to send email alert: {e}")
            return False
        
        return True  # 非错误级别的告警不发送邮件


class WebhookAlertHandler(AlertHandler):
    """Webhook告警处理器"""
    
    def __init__(self, webhook_url: str, timeout: int = 5):
        self.webhook_url = webhook_url
        self.timeout = timeout
    
    def handle_alert(self, alert: Alert) -> bool:
        """发送Webhook告警"""
        try:
            payload = {
                'alert': alert.to_dict(),
                'source': 'creeps_battle_monitoring'
            }
            
            response = requests.post(
                self.webhook_url,
                json=payload,
                timeout=self.timeout
            )
            
            if response.status_code == 200:
                return True
            else:
                logger.warning(f"Webhook alert failed with status {response.status_code}")
                return False
                
        except Exception as e:
            logger.error(f"Failed to send webhook alert: {e}")
            return False


class BattleServerMonitor:
    """战斗服务器监控器"""
    
    def __init__(self, node_server_manager):
        self.node_server_manager = node_server_manager
        self.alert_handlers: List[AlertHandler] = []
        self.metrics_history: List[MonitoringMetrics] = []
        self.alerts_history: List[Alert] = []
        self.is_running = False
        self._monitor_thread = None
        self._lock = threading.RLock()
        
        # CPU使用率计算相关
        self._last_cpu_call_time = None
        self._cpu_percent_history = []
        self._cpu_history_size = 5  # 保留最近5次的CPU使用率用于平均计算
        
        # 从Django设置获取配置
        monitoring_config = getattr(settings, 'MONITORING', {})
        self.config = {
            'enabled': monitoring_config.get('ENABLED', True),
            'metrics_retention_hours': monitoring_config.get('METRICS_RETENTION_HOURS', 24),
            'alert_cooldown_minutes': monitoring_config.get('ALERT_COOLDOWN_MINUTES', 5),
            'health_check_interval': monitoring_config.get('HEALTH_CHECK_INTERVAL', 30),
            'alert_handlers': monitoring_config.get('ALERT_HANDLERS', {})
        }
        
        # 配置参数
        self.monitor_interval = getattr(settings, 'BATTLE_MONITOR_INTERVAL', 30)  # 30秒
        self.metrics_retention_hours = getattr(settings, 'BATTLE_MONITOR_METRICS_RETENTION', 24)  # 24小时
        self.alerts_retention_hours = getattr(settings, 'BATTLE_MONITOR_ALERTS_RETENTION', 72)  # 72小时
        
        # 告警阈值
        self.port_exhaustion_threshold = getattr(settings, 'BATTLE_MONITOR_PORT_EXHAUSTION_THRESHOLD', 0.9)  # 90%
        self.memory_usage_threshold = getattr(settings, 'BATTLE_MONITOR_MEMORY_THRESHOLD', 0.8)  # 80%
        self.cpu_usage_threshold = getattr(settings, 'BATTLE_MONITOR_CPU_THRESHOLD', 0.8)  # 80%
        self.unhealthy_servers_threshold = getattr(settings, 'BATTLE_MONITOR_UNHEALTHY_THRESHOLD', 0.3)  # 30%
        
        # 初始化告警处理器
        self._init_alert_handlers()
        
        # 记录启动时间
        self.start_time = timezone.now()
        
        # 初始化CPU使用率（第一次调用会返回0.0，我们忽略它）
        try:
            psutil.cpu_percent(interval=None)
        except Exception:
            pass
    
    def _get_cpu_percent(self) -> float:
        """获取优化的CPU使用率"""
        current_time = time.time()
        
        # 检查是否有足够的时间间隔（至少0.1秒）
        if self._last_cpu_call_time is not None:
            time_diff = current_time - self._last_cpu_call_time
            if time_diff < 0.1:
                # 如果时间间隔太短，使用历史平均值
                if self._cpu_percent_history:
                    return sum(self._cpu_percent_history) / len(self._cpu_percent_history)
                else:
                    # 如果没有历史数据，使用阻塞调用获取准确值
                    try:
                        cpu_percent = psutil.cpu_percent(interval=0.1)
                        self._last_cpu_call_time = time.time()
                        return cpu_percent
                    except Exception:
                        return 0.0
        
        try:
            # 使用非阻塞调用
            cpu_percent = psutil.cpu_percent(interval=None)
            
            # 更新历史记录
            self._cpu_percent_history.append(cpu_percent)
            if len(self._cpu_percent_history) > self._cpu_history_size:
                self._cpu_percent_history.pop(0)
            
            self._last_cpu_call_time = current_time
            
            # 如果获取到的值为0且有历史数据，可能是第一次调用或间隔太短
            if cpu_percent == 0.0 and len(self._cpu_percent_history) > 1:
                # 返回历史平均值（排除当前的0值）
                valid_history = [x for x in self._cpu_percent_history[:-1] if x > 0]
                if valid_history:
                    return sum(valid_history) / len(valid_history)
            
            return cpu_percent
            
        except Exception as e:
            logger.warning(f"获取CPU使用率失败: {e}")
            # 返回历史平均值作为备选
            if self._cpu_percent_history:
                return sum(self._cpu_percent_history) / len(self._cpu_percent_history)
            return 0.0
    
    def _init_alert_handlers(self):
        """初始化告警处理器"""
        handlers_config = self.config.get('alert_handlers', {})
        
        # 日志处理器
        log_config = handlers_config.get('LOG', {})
        if log_config.get('ENABLED', True):
            self.alert_handlers.append(LogAlertHandler())
        
        # 邮件处理器
        email_config = handlers_config.get('EMAIL', {})
        if email_config.get('ENABLED', False):
            self.alert_handlers.append(EmailAlertHandler(
                smtp_host=email_config.get('SMTP_HOST', 'localhost'),
                smtp_port=email_config.get('SMTP_PORT', 587),
                smtp_user=email_config.get('SMTP_USER', ''),
                smtp_password=email_config.get('SMTP_PASSWORD', ''),
                from_email=email_config.get('FROM_EMAIL', 'noreply@creeps-battle.com'),
                to_emails=email_config.get('TO_EMAILS', [])
            ))
        
        # Webhook处理器
        webhook_config = handlers_config.get('WEBHOOK', {})
        if webhook_config.get('ENABLED', False):
            self.alert_handlers.append(WebhookAlertHandler(
                webhook_url=webhook_config.get('URL', ''),
                timeout=webhook_config.get('TIMEOUT', 10)
            ))
    
    def start_monitoring(self):
        """开始监控"""
        with self._lock:
            if self.is_running:
                logger.warning("Monitor is already running")
                return
            
            self.is_running = True
            self._monitor_thread = threading.Thread(target=self._monitor_loop, daemon=True)
            self._monitor_thread.start()
            logger.info("Battle server monitoring started")
    
    def stop_monitoring(self):
        """停止监控"""
        with self._lock:
            if not self.is_running:
                return
            
            self.is_running = False
            if self._monitor_thread:
                self._monitor_thread.join(timeout=5)
            logger.info("Battle server monitoring stopped")
    
    def _monitor_loop(self):
        """监控循环"""
        while self.is_running:
            try:
                # 收集指标
                metrics = self._collect_metrics()
                
                # 检查告警条件
                self._check_alerts(metrics)
                
                # 保存指标
                self._save_metrics(metrics)
                
                # 清理历史数据
                self._cleanup_history()
                
            except Exception as e:
                logger.error(f"Monitor loop error: {e}")
                self._send_alert(Alert(
                    alert_type=AlertType.CONNECTION_ERROR,
                    level=AlertLevel.ERROR,
                    message=f"监控循环异常: {str(e)}"
                ))
            
            # 等待下一次检查
            time.sleep(self.monitor_interval)
    
    def _collect_metrics(self) -> MonitoringMetrics:
        """收集监控指标"""
        try:
            # 获取服务器统计信息
            server_stats = self.node_server_manager.get_stats()
            
            # 获取系统资源使用情况
            cpu_percent = self._get_cpu_percent()
            memory = psutil.virtual_memory()
            disk = psutil.disk_usage('/')
            
            # 获取网络连接数
            network_connections = len(psutil.net_connections())
            
            # 获取详细的CPU信息
            cpu_count = psutil.cpu_count()
            cpu_freq = psutil.cpu_freq()
            cpu_freq_current = cpu_freq.current if cpu_freq else 0.0
            cpu_freq_max = cpu_freq.max if cpu_freq else 0.0
            
            # 获取详细的磁盘分区信息
            disk_partitions = []
            for partition in psutil.disk_partitions():
                try:
                    partition_usage = psutil.disk_usage(partition.mountpoint)
                    disk_partitions.append({
                        'device': partition.device,
                        'mountpoint': partition.mountpoint,
                        'fstype': partition.fstype,
                        'total': partition_usage.total,
                        'used': partition_usage.used,
                        'free': partition_usage.free,
                        'usage_percent': (partition_usage.used / partition_usage.total * 100) if partition_usage.total > 0 else 0
                    })
                except (PermissionError, OSError):
                    # 跳过无法访问的分区
                    continue
            
            # 获取网络IO统计
            network_io = psutil.net_io_counters()
            network_io_sent = network_io.bytes_sent if network_io else 0
            network_io_recv = network_io.bytes_recv if network_io else 0
            
            # 获取系统负载平均值（仅在Unix系统上可用）
            load_average = []
            try:
                if hasattr(psutil, 'getloadavg'):
                    load_average = list(psutil.getloadavg())
            except (AttributeError, OSError):
                # Windows系统不支持getloadavg
                pass
            
            # 获取系统启动时间
            boot_time = psutil.boot_time()
            
            # 获取进程数统计
            process_count = len(psutil.pids())
            python_process_count = 0
            django_process_count = 0
            
            try:
                for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
                    try:
                        proc_info = proc.info
                        if proc_info['name'] and 'python' in proc_info['name'].lower():
                            python_process_count += 1
                            # 检查是否是Django进程
                            if proc_info['cmdline']:
                                cmdline = ' '.join(proc_info['cmdline']).lower()
                                if 'django' in cmdline or 'manage.py' in cmdline or 'runserver' in cmdline:
                                    django_process_count += 1
                    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                        continue
            except Exception as e:
                logger.warning(f"Failed to collect process statistics: {e}")
            
            # 获取请求统计
            request_count_total = 0
            request_count_per_minute = 0.0
            
            try:
                from .request_counter import get_request_counter
                request_counter = get_request_counter()
                request_count_total = request_counter.get_total_requests()
                request_count_per_minute = request_counter.get_requests_per_minute()
            except ImportError:
                logger.warning("Request counter not available")
            except Exception as e:
                logger.warning(f"Failed to collect request statistics: {e}")
            
            metrics = MonitoringMetrics(
                total_servers=server_stats['total_servers'],
                running_servers=server_stats['running_servers'],
                unhealthy_servers=server_stats['error_servers'],
                used_ports=server_stats['used_ports'],
                available_ports=server_stats['available_ports'],
                cpu_usage=cpu_percent,
                memory_usage=memory.percent,
                disk_usage=disk.percent,
                network_connections=network_connections,
                # 新增详细系统资源信息
                cpu_count=cpu_count,
                cpu_freq_current=cpu_freq_current,
                cpu_freq_max=cpu_freq_max,
                memory_total=memory.total,
                memory_available=memory.available,
                memory_used=memory.used,
                disk_total=disk.total,
                disk_used=disk.used,
                disk_free=disk.free,
                disk_partitions=disk_partitions,
                network_io_sent=network_io_sent,
                network_io_recv=network_io_recv,
                load_average=load_average,
                boot_time=boot_time,
                # 新增进程和请求统计
                process_count=process_count,
                python_process_count=python_process_count,
                django_process_count=django_process_count,
                request_count_total=request_count_total,
                request_count_per_minute=request_count_per_minute
            )
            
            return metrics
            
        except Exception as e:
            logger.error(f"Failed to collect metrics: {e}")
            return MonitoringMetrics()
    
    def _check_alerts(self, metrics: MonitoringMetrics):
        """检查告警条件"""
        # 检查端口耗尽
        if metrics.available_ports > 0:
            port_usage_ratio = metrics.used_ports / (metrics.used_ports + metrics.available_ports)
            if port_usage_ratio >= self.port_exhaustion_threshold:
                self._send_alert(Alert(
                    alert_type=AlertType.PORT_EXHAUSTION,
                    level=AlertLevel.WARNING,
                    message=f"端口使用率过高: {port_usage_ratio:.1%} (阈值: {self.port_exhaustion_threshold:.1%})",
                    metadata={'port_usage_ratio': port_usage_ratio, 'used_ports': metrics.used_ports}
                ))
        
        # 检查不健康服务器比例
        if metrics.total_servers > 0:
            unhealthy_ratio = metrics.unhealthy_servers / metrics.total_servers
            if unhealthy_ratio >= self.unhealthy_servers_threshold:
                self._send_alert(Alert(
                    alert_type=AlertType.SERVER_UNHEALTHY,
                    level=AlertLevel.ERROR,
                    message=f"不健康服务器比例过高: {unhealthy_ratio:.1%} (阈值: {self.unhealthy_servers_threshold:.1%})",
                    metadata={'unhealthy_ratio': unhealthy_ratio, 'unhealthy_count': metrics.unhealthy_servers}
                ))
        
        # 检查内存使用率
        if metrics.memory_usage >= self.memory_usage_threshold * 100:
            self._send_alert(Alert(
                alert_type=AlertType.HIGH_MEMORY_USAGE,
                level=AlertLevel.WARNING,
                message=f"内存使用率过高: {metrics.memory_usage:.1f}% (阈值: {self.memory_usage_threshold * 100:.1f}%)",
                metadata={'memory_usage': metrics.memory_usage}
            ))
        
        # 检查CPU使用率
        if metrics.cpu_usage >= self.cpu_usage_threshold * 100:
            self._send_alert(Alert(
                alert_type=AlertType.HIGH_CPU_USAGE,
                level=AlertLevel.WARNING,
                message=f"CPU使用率过高: {metrics.cpu_usage:.1f}% (阈值: {self.cpu_usage_threshold * 100:.1f}%)",
                metadata={'cpu_usage': metrics.cpu_usage}
            ))
    
    def _send_alert(self, alert: Alert):
        """发送告警"""
        with self._lock:
            # 保存告警历史
            self.alerts_history.append(alert)
            
            # 发送给所有处理器
            for handler in self.alert_handlers:
                try:
                    handler.handle_alert(alert)
                except Exception as e:
                    logger.error(f"Alert handler failed: {e}")
    
    def _save_metrics(self, metrics: MonitoringMetrics):
        """保存指标"""
        with self._lock:
            self.metrics_history.append(metrics)
    
    def _cleanup_history(self):
        """清理历史数据"""
        with self._lock:
            now = timezone.now()
            
            # 清理指标历史
            metrics_cutoff = now - timedelta(hours=self.metrics_retention_hours)
            self.metrics_history = [
                m for m in self.metrics_history 
                if m.timestamp >= metrics_cutoff
            ]
            
            # 清理告警历史
            alerts_cutoff = now - timedelta(hours=self.alerts_retention_hours)
            self.alerts_history = [
                a for a in self.alerts_history 
                if a.timestamp >= alerts_cutoff
            ]
    
    def get_current_metrics(self) -> Optional[MonitoringMetrics]:
        """获取当前指标"""
        with self._lock:
            if self.metrics_history:
                return self.metrics_history[-1]
            return None
    
    def get_metrics_history(self, hours: int = 1) -> List[MonitoringMetrics]:
        """获取指标历史"""
        with self._lock:
            cutoff = timezone.now() - timedelta(hours=hours)
            return [m for m in self.metrics_history if m.timestamp >= cutoff]
    
    def get_alerts_history(self, hours: int = 24) -> List[Alert]:
        """获取告警历史"""
        with self._lock:
            cutoff = timezone.now() - timedelta(hours=hours)
            return [a for a in self.alerts_history if a.timestamp >= cutoff]
    
    def get_recent_alerts(self, limit: int = 10) -> List[Alert]:
        """获取最近的告警"""
        with self._lock:
            # 按时间倒序排列，返回最近的告警
            sorted_alerts = sorted(self.alerts_history, key=lambda x: x.timestamp, reverse=True)
            return sorted_alerts[:limit]
    
    def clear_alerts(self, alert_ids: List[str]):
        """清除指定的告警"""
        with self._lock:
            # 为告警添加ID字段用于清除
            self.alerts_history = [a for a in self.alerts_history 
                                 if getattr(a, 'id', None) not in alert_ids]
    
    def clear_all_alerts(self):
        """清除所有告警"""
        with self._lock:
            self.alerts_history.clear()
    
    def get_system_metrics(self) -> Dict:
        """获取系统指标"""
        from .models import Battle
        
        current_metrics = self.get_current_metrics()
        if not current_metrics:
            return {}
        
        # 计算运行时间
        uptime_seconds = (timezone.now() - getattr(self, 'start_time', timezone.now())).total_seconds()
        
        # 统计活跃战斗数（状态为'running'的战斗）
        active_battles = Battle.objects.filter(status='running').count()
        
        # 格式化内存和磁盘大小
        def format_bytes(bytes_value):
            """将字节数转换为人类可读的格式"""
            for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
                if bytes_value < 1024.0:
                    return f"{bytes_value:.1f} {unit}"
                bytes_value /= 1024.0
            return f"{bytes_value:.1f} PB"
        
        # 计算系统运行时间（从启动到现在）
        system_uptime_seconds = time.time() - current_metrics.boot_time if current_metrics.boot_time > 0 else 0
        
        return {
            # 基础指标
            'running_servers': current_metrics.running_servers,
            'total_servers': current_metrics.total_servers,
            'unhealthy_servers': current_metrics.unhealthy_servers,
            'active_battles': active_battles,
            'total_alerts': len(self.alerts_history),
            'uptime_seconds': uptime_seconds,
            'last_updated': timezone.now().isoformat(),
            
            # CPU信息
            'cpu': {
                'usage_percent': current_metrics.cpu_usage,
                'count': current_metrics.cpu_count,
                'freq_current': current_metrics.cpu_freq_current,
                'freq_max': current_metrics.cpu_freq_max,
                'load_average': current_metrics.load_average
            },
            
            # 内存信息
            'memory': {
                'usage_percent': current_metrics.memory_usage,
                'total': current_metrics.memory_total,
                'used': current_metrics.memory_used,
                'available': current_metrics.memory_available,
                'total_formatted': format_bytes(current_metrics.memory_total),
                'used_formatted': format_bytes(current_metrics.memory_used),
                'available_formatted': format_bytes(current_metrics.memory_available)
            },
            
            # 磁盘信息
            'disk': {
                'usage_percent': current_metrics.disk_usage,
                'total': current_metrics.disk_total,
                'used': current_metrics.disk_used,
                'free': current_metrics.disk_free,
                'total_formatted': format_bytes(current_metrics.disk_total),
                'used_formatted': format_bytes(current_metrics.disk_used),
                'free_formatted': format_bytes(current_metrics.disk_free),
                'partitions': current_metrics.disk_partitions
            },
            
            # 网络信息
            'network': {
                'connections': current_metrics.network_connections,
                'io_sent': current_metrics.network_io_sent,
                'io_recv': current_metrics.network_io_recv,
                'io_sent_formatted': format_bytes(current_metrics.network_io_sent),
                'io_recv_formatted': format_bytes(current_metrics.network_io_recv)
            },
            
            # 进程信息
            'processes': {
                'total_count': current_metrics.process_count,
                'python_count': current_metrics.python_process_count,
                'django_count': current_metrics.django_process_count
            },
            
            # 请求信息
            'requests': {
                'total_count': current_metrics.request_count_total,
                'per_minute': current_metrics.request_count_per_minute
            },
            
            # 系统信息
            'system': {
                'boot_time': current_metrics.boot_time,
                'uptime_seconds': system_uptime_seconds
            }
        }
    
    def send_manual_alert(self, alert_type: AlertType, level: AlertLevel, message: str, 
                         battle_id: Optional[str] = None, port: Optional[int] = None, 
                         metadata: Optional[Dict] = None):
        """手动发送告警"""
        alert = Alert(
            alert_type=alert_type,
            level=level,
            message=message,
            battle_id=battle_id,
            port=port,
            metadata=metadata or {}
        )
        self._send_alert(alert)


# 全局监控器实例
_monitor_instance = None
_monitor_lock = threading.Lock()


def get_battle_monitor(node_server_manager=None) -> BattleServerMonitor:
    """获取全局监控器实例"""
    global _monitor_instance
    
    with _monitor_lock:
        if _monitor_instance is None:
            if node_server_manager is None:
                from .node_server_manager import node_server_manager as default_manager
                node_server_manager = default_manager
            
            _monitor_instance = BattleServerMonitor(node_server_manager)
            
            # 自动启动监控（如果配置启用）
            if getattr(settings, 'BATTLE_MONITOR_AUTO_START', True):
                _monitor_instance.start_monitoring()
        
        return _monitor_instance


def send_battle_alert(alert_type: AlertType, level: AlertLevel, message: str, 
                     battle_id: Optional[str] = None, port: Optional[int] = None, 
                     metadata: Optional[Dict] = None):
    """发送战斗告警的便捷函数"""
    monitor = get_battle_monitor()
    monitor.send_manual_alert(alert_type, level, message, battle_id, port, metadata)